element Plus的虚拟化表格用的是lang=tsx,先安装
cnpm i @vitejs/plugin-vue-jsx然后去vite.config.ts里加配置
import vueJsx from '@vitejs/plugin-vue-jsx' plugins: [vue(),vueJsx(),]再去tsconfig.json中加东西
// 不要把compilerOptions里的删掉,往里塞就行"compilerOptions": { "jsx": "preserve","jsxFactory": "h","jsxFragmentFactory": "Fragment",}然后去要使用的的页面
把lang=ts改成lang=tsx
.....然后开始改造你的代码
上图是el-table的数据格式,先改造表头数据tableOps
虚拟化表格的columns键是固定的,不能修改
{title: '员工姓名',key: 'userName',align: 'center', // 是否居中dataKey: 'userName', width: 120,fixed: 'left' // 是否固定在左边},// title就是表头名dataKey就是对应返回数据的字段, key不知道干嘛用的,最好带着然后表格的html代码就变成这样。 load是滚动条滑到底部时的事件
定义表头字段
// 全部的表头const headOps = ref([])// 固定的几个表头字段const tableOps = ref([{title: '序号',key: 'index',align: 'center',dataKey: 'index',width: 120,fixed: 'left',cellRenderer: (cellData: any) => ({cellData.rowIndex +1 })},{title: '员工姓名',key: 'userName',align: 'center',dataKey: 'userName',width: 120,fixed: 'left'},{title: '岗位',fixed: 'left',align: 'center',width: 120,key: 'positionName',dataKey: 'positionName',}, ])官方文档是在这自定义的
先添加操作项
el-table样式
虚拟化改造:
先建立操作项表头数据
list = { title: '操作',key: 'ops',align: 'center',dataKey: 'ops',width: 150,fixed: 'right',cellRenderer: (cellData: any) => ( { !cellData.rowData.isEdit && authorization('attendanceTable_edit') ? updateRow(cellData.rowData)} > 修改 : ''}{ cellData.rowData.isEdit && authorization('attendanceTable_edit') ? submit(cellData.rowData)} > 提交 : ''}{ cellData.rowData.isEdit && authorization('attendanceTable_edit') ? cancelSubmit(cellData.rowData)} > 取消 : ''} )}tsx中没有v-if.所以要用三元表达式来操作v-if的展示内容
cellData返回几个对象
cellData, // 要展示的数据rowData, // 相当于scope.row, 这一行的数据rowIndex, // 行序号,从0开始,tsx中没有{{}} , 只有单括号, 不能在div直接写变量的,要用{}包起来
v-model的话就是把等号后边的“”换成{}就可以了,例如
@click换成onClick,然后用{}包住定义的方法,有参数的话要写成
onClick={() => updateRow(cellData.rowData)}// 点击修改const updateRow = (row: any) => {row.isEdit = truefor (let valueKey in editParams.value) {editParams.value[valueKey] = row[valueKey]}}方法还是正常定义
页面全部代码
查询导出推送企信当前页:{{ searchVal.pageIndex }}/总共{{ total}}条import {Search,Refresh,Position,Upload} from '@element-plus/icons-vue'import {authorization} from "../../../utils/auth";import {nextTick, onMounted, ref, h} from "vue";import LeftCompanyMenu from "./leftCompanyMenu.vue";import Stable from "../../../components/table/Stable.vue";import {getAttendanceTableList, getDetailById,updateAttendance,} from "../../../api/humanResources/attendanceTableList";import {ElMessage, ElMessageBox} from "element-plus";import dayjs from "dayjs";import AttendanceListDialog from "./attendanceListDialog.vue";import PushQXDialog from "./pushQXDialog.vue";import axios from "axios";import {exportData} from "../../../utils/export";const leftTree = ref()const total = ref(0)const loading = ref(false)const isShowDialog = ref(false)const isShowPushDialog = ref(false)// 要查询的月份const selectedDate = ref()const permissionTag = ref()const itemInfo = ref()// 点击详情返回的经纬度信息const mapData = ref([])const tableData = ref([])const canEditCloumn = ref([{label: '应出勤天数',type: '',data: null,key: 'shouldBeAttendedOnDays'},{label: '实际出勤',type: '',width: 100,key: 'actualAttendance'},{label: '值班小时',type: '',width: 100,key: 'dutyHours'},{label: '出差',type: '',key: 'businessTrip'},{label: '外出登记',type: '',width: 100,key: 'goOutAndRegister'},{label: '探亲假',type: '',key: 'familyLeave'},{label: '年假',type: '',key: 'annualLeave'},{label: '调休',type: '',key: 'rest'},{label: '事假',type: '',key: 'leave'},{label: '高管带薪事假',type: '',width: 110,key: 'executivePaidPersonalLeave'},{label: '病假',type: '',key: 'sickLeave'},{label: '丧假',type: '',key: 'bereavementLeave'},{label: '婚假',type: '',key: 'marriageLeave'},{label: '产假',type: '',key: 'maternityLeave'},{label: '陪产假',type: '',key: 'paternityLeave'},{label: '产检假',type: '',key: 'maternityExamineLeave'},{label: '育儿假',type: '',key: 'parentalLeave'},{label: '哺乳假',type: '',key: 'breastfeedingLeave'},{label: '工伤假',type: '',key: 'injuryLeave'},{label: '未打卡',type: '',key: 'notClockedOut'},{label: '迟到',type: '',key: 'late'},{label: '早退',type: '',key: 'early'},{label: '旷工',type: '',key: 'absenteeism'},])const headOps = ref([])const tableOps = ref([{title: '序号',key: 'index',align: 'center',dataKey: 'index',width: 120,fixed: 'left',cellRenderer: (cellData: any) => {console.log(cellData)}// (// {cellData.rowIndex +1 }// )},{title: '员工姓名',key: 'userName',align: 'center',dataKey: 'userName',width: 120,fixed: 'left'},{title: '岗位',fixed: 'left',align: 'center',width: 120,key: 'positionName',dataKey: 'positionName',},{title: '公司',align: 'center',key: 'companyName',dataKey: 'companyName',width: 160,},{title: '部门',width: 120,align: 'center',key: 'deptName',dataKey: 'deptName',},{title: '是否全勤',width: 120,align: 'center',key: 'fullAttendance',dataKey: 'fullAttendance',cellRenderer: (cellData: any) => ({ cellData.cellData ? '全勤' : '缺勤'})},{title: '核对状态',width: 100,align: 'center',key: 'checkStatus',dataKey: 'checkStatus',cellRenderer: (cellData: any) => ({ cellData.rowData.checkStatus ? 已核对 : '未核对'})},{title: '推送次数',width: 100,align: 'center',key: 'theNumberOfPushes',dataKey: 'theNumberOfPushes',},{title: '应出勤天数',width: 100,align: 'center',key: 'shouldBeAttendedOnDays',dataKey: 'shouldBeAttendedOnDays',cellRenderer: (cellData: any) => ({cellData.rowData.isEdit ? : {cellData.rowData.shouldBeAttendedOnDays}})},{title: '实际出勤',width: 100,align: 'center',key: 'actualAttendance',dataKey: 'actualAttendance',cellRenderer: (cellData: any) => ({cellData.rowData.isEdit ? : {cellData.rowData.actualAttendance}})},{title: '值班小时',width: 100,align: 'center',key: 'dutyHours',dataKey: 'dutyHours',cellRenderer: (cellData: any) => ({cellData.rowData.isEdit ? : {cellData.rowData.dutyHours}})},{title: '出差',width: 120,align: 'center',key: 'businessTrip',dataKey: 'businessTrip',cellRenderer: (cellData: any) => ({cellData.rowData.isEdit ? : {cellData.rowData.businessTrip}})},{title: '外出登记',width: 100,align: 'center',key: 'goOutAndRegister',dataKey: 'goOutAndRegister',cellRenderer: (cellData: any) => ({cellData.rowData.isEdit ? : {cellData.rowData.goOutAndRegister}})},{title: '探亲假',width: 120,align: 'center',key: 'familyLeave',dataKey: 'familyLeave',cellRenderer: (cellData: any) => ({cellData.rowData.isEdit ? : {cellData.rowData.familyLeave}})},{title: '年假',width: 120,align: 'center',key: 'annualLeave',dataKey: 'annualLeave',cellRenderer: (cellData: any) => ({cellData.rowData.isEdit ? : {cellData.rowData.annualLeave}})},{title: '调休',key: 'rest',align: 'center',width: 120,dataKey: 'rest',cellRenderer: (cellData: any) => ({cellData.rowData.isEdit ? : {cellData.rowData.rest}})},{title: '事假',key: 'leave',align: 'center',width: 120,dataKey: 'leave',cellRenderer: (cellData: any) => ({cellData.rowData.isEdit ? : {cellData.rowData.leave}})},{title: '高管带薪事假',width: 110,align: 'center',key: 'executivePaidPersonalLeave',dataKey: 'executivePaidPersonalLeave',cellRenderer: (cellData: any) => ({cellData.rowData.isEdit ? : {cellData.rowData.executivePaidPersonalLeave}})},{title: '病假',width: 100,align: 'center',key: 'sickLeave',dataKey: 'sickLeave',cellRenderer: (cellData: any) => ({cellData.rowData.isEdit ? : {cellData.rowData.sickLeave}})},{title: '丧假',width: 80,align: 'center',key: 'bereavementLeave',dataKey: 'bereavementLeave',cellRenderer: (cellData: any) => ({cellData.rowData.isEdit ? : {cellData.rowData.bereavementLeave}})},{title: '婚假',width: 80,align: 'center',key: 'marriageLeave',dataKey: 'marriageLeave',cellRenderer: (cellData: any) => ({cellData.rowData.isEdit ? : {cellData.rowData.marriageLeave}})},{title: '产假',width: 80,align: 'center',key: 'maternityLeave',dataKey: 'maternityLeave',cellRenderer: (cellData: any) => ({cellData.rowData.isEdit ? : {cellData.rowData.maternityLeave}})},{title: '陪产假',width: 80,align: 'center',key: 'paternityLeave',dataKey: 'paternityLeave',cellRenderer: (cellData: any) => ({cellData.rowData.isEdit ? : {cellData.rowData.paternityLeave}})},{title: '产检假',width: 80,align: 'center',key: 'maternityExamineLeave',dataKey: 'maternityExamineLeave',cellRenderer: (cellData: any) => ({cellData.rowData.isEdit ? : {cellData.rowData.maternityExamineLeave}})},{title: '育儿假',width: 80,align: 'center',key: 'parentalLeave',dataKey: 'parentalLeave',cellRenderer: (cellData: any) => ({cellData.rowData.isEdit ? : {cellData.rowData.parentalLeave}})},{title: '哺乳假',width: 80,align: 'center',key: 'breastfeedingLeave',dataKey: 'breastfeedingLeave',cellRenderer: (cellData: any) => ({cellData.rowData.isEdit ? : {cellData.rowData.breastfeedingLeave}})},{title: '工伤假',width: 80,align: 'center',key: 'injuryLeave',dataKey: 'injuryLeave',cellRenderer: (cellData: any) => ({cellData.rowData.isEdit ? : {cellData.rowData.injuryLeave}})},{title: '未打卡',width: 80,align: 'center',key: 'notClockedOut',dataKey: 'notClockedOut',cellRenderer: (cellData: any) => ({cellData.rowData.isEdit ? : {cellData.rowData.notClockedOut}})},{title: '迟到',width: 80,align: 'center',key: 'late',dataKey: 'late',cellRenderer: (cellData: any) => ({cellData.rowData.isEdit ? : {cellData.rowData.late}})},{title: '早退',width: 80,align: 'center',key: 'early',dataKey: 'early',cellRenderer: (cellData: any) => ({cellData.rowData.isEdit ? : {cellData.rowData.early}})},{title: '旷工',width: 80,align: 'center',key: 'absenteeism',dataKey: 'absenteeism',cellRenderer: (cellData: any) => ({cellData.rowData.isEdit ? : {cellData.rowData.absenteeism}})},])const weekData = ref([{weekName: '周一',index: 1,},{weekName: '周二',index: 2,},{weekName: '周三',index: 3,},{weekName: '周四',index: 4,},{weekName: '周五',index: 5,},{weekName: '周六',index: 6,},{weekName: '周日',index: 0,}])const canSearch = ref(false)const isCanEdit = ref(false)const hasRes = ref(true)const weekList: any = ref([])const headWeek: any = ref([])const searchVal: any = ref({startTime: '',workCode: null,userNames: null,endTime: '',type: null,queryId: null,pageIndex: 1,pageSize: 500,})const editParams: any = ref({shouldBeAttendedOnDays: null,actualAttendance: null,dutyHours: null,businessTrip: null,goOutAndRegister: null,familyLeave: null,annualLeave: null,rest: null,leave: null,executivePaidPersonalLeave: null,sickLeave: null,bereavementLeave: null,marriageLeave: null,maternityLeave: null,paternityLeave: null,maternityExamineLeave: null,parentalLeave: null,breastfeedingLeave : null,injuryLeave: null,notClockedOut: null,late: null,early: null,absenteeism: null})const haOps = ref(true)// 是否含有权限const hasNoPrivilege = (val: boolean) => {canSearch.value = val}// 点击左侧公司const getCompanyDeptInfo = async (val: any) => {const { id } = valsearchVal.value.queryId = idsearchVal.value.pageIndex = 1searchVal.value.pageSize = 500await getListData()}// 选择完时间const changeDate = (val: any) => {searchVal.value.startTime = dayjs(val).startOf('M').format('YYYY-MM-DD')searchVal.value.endTime = dayjs(val).endOf('M').format('YYYY-MM-DD')getListData()}// 设置当月第一天和最后一天const setSearchValDate = (val: any) =>{searchVal.value.startTime = dayjs(val).startOf('M').format('YYYY-MM-DD')searchVal.value.endTime = dayjs(val).endOf('M').format('YYYY-MM-DD')}// 动态生成表头const creatHead = (monthData: any) => {headOps.value = [...tableOps.value, ...monthData]// 选择当月之前的时间可以编辑数据haOps.value = headOps.value.some((item:any) => item.key === 'ops')if ( dayjs().isAfter(selectedDate.value, 'month')){if (!haOps.value){headOps.value.push({title: '操作',key: 'ops',align: 'center',dataKey: 'ops',width: 150,fixed: 'right',cellRenderer: (cellData: any) => ({ !cellData.rowData.isEdit && authorization('attendanceTable_edit') ? updateRow(cellData.rowData)} > 修改 : ''}{ cellData.rowData.isEdit && authorization('attendanceTable_edit') ? submit(cellData.rowData)} > 提交 : ''}{ cellData.rowData.isEdit && authorization('attendanceTable_edit') ? cancelSubmit(cellData.rowData)} > 取消 : ''})})}}else {// 删除操作项if (haOps.value){headOps.value.pop()}}}// 获取月表头const getMonthHeader = (date: any) => {weekList.value = []headWeek.value = []// 获取第一天是周几const firstDay = dayjs(date).startOf('M')// 获取当月总天数const sum = dayjs(date).daysInMonth()for (let i = 0; i item.index === week)weekList.value.push({date: dayjs(itemDate).format('YYYY-MM-DD'),weekName: weekName[0].weekName,dateNum: dayjs(itemDate).format('DD')})}for (let i = 0; i ({ cellData.cellData }{ cellData.rowData.positionName=== '客户经理' ? goToDetail(cellData.column, cellData.rowData)}>详 : ''})})}// positionNamecreatHead(headWeek.value)}// 导出const exportTableData = () => {axios({method: 'get',url: 'api/attendance-server/attendance/user/statistics/check/history/export', // 请求地址responseType: 'blob', // 表明返回服务器返回的数据类型params: {dateTime: dayjs(searchVal.value.startTime).format('YYYY-MM-DD'), queryId: searchVal.value.queryId},headers: {"Content-Type": "application/json, text/plain, */*",Authorization: localStorage.getItem('token') as string,}}).then( (res: any) => {if (res.code) {ElMessage.warning(res.message);return}exportData('考勤统计.xlsx', res.data)})}// 获取列表const getListData = () => {if (searchVal.value.queryId){searchVal.value.type = searchVal.value.queryId === '1' ? null : 1if (canSearch.value){searchVal.value.pageIndex = 1tableData.value = [];loading.value = true;getMonthHeader(selectedDate.value)getAttendanceTableList(searchVal.value).then(res => {if (res && res.data) {const { count, results } = res.data;total.value = count;tableData.value = [...results];for (let i = 0; i 0) {for (let j = 0; j {itemInfo.value = rowgetDetailById({date: val.key, userId: row.userId}).then(res => {if (res && res.data.length > 0) {isShowDialog.value = truemapData.value = res.data}else {isShowDialog.value = falseElMessage.error('暂无打卡数据')}})}// 弹窗关闭回调const beforeClose = () => {isShowDialog.value = false}// 上滑滚动const onSearchInfinite = () => {loading.value = truegetAttendanceTableList(searchVal.value).then(res => {if (res?.code == 0) {const { results } = res.data;for (let i = 0; i 0) {for (let j = 0; j {if (tableData.value.length > 0){if (total.value > tableData.value.length) {searchVal.value.pageIndex++await onSearchInfinite()}}}// 分页const handleCurrentChange = (val: number) => {searchVal.value.pageIndex = valgetListData()}const handleSizeChange = (val: number) => {searchVal.value.pageSize = valsearchVal.value.pageIndex = 1getListData()}// 点击修改const updateRow = (row: any) => {row.isEdit = truefor (let valueKey in editParams.value) {editParams.value[valueKey] = row[valueKey]}}// 点击提交const submit = (row: any) => {row.month = dayjs(selectedDate.value).format('YYYY-MM')row = {...row, ...editParams.value}updateAttendance(row).then((res: any) => {if (res && res.code === 0){ElMessage.success('提交成功')getListData()}})}// 取消const cancelSubmit = (row: any) => {row.isEdit = false}// 重置const reset = () => {const nowDay = dayjs().format('YYYY-MM-DD')selectedDate.value = nowDaysearchVal.value = {startTime: '',endTime: '',queryId: '1',pageIndex: 1,pageSize: 500,}setSearchValDate(nowDay)getMonthHeader(new Date())leftTree.value.getCompanyDepartmentTree()getListData()}// 推送企信const pushQX = () => {isShowPushDialog.value = true}const closePushDialog = () => {isShowPushDialog.value = false}onMounted(() => {const nowDay = dayjs().format('YYYY-MM-DD')selectedDate.value = nowDaypermissionTag.value = 'attendance_statistics'setSearchValDate(nowDay)getMonthHeader(nowDay)})::v-deep(.el-table-v2__row.is-hovered){background-color: #FFFFFF;}::v-deep(.el-empty__image){display: none;}.attendanceTableList{display: flex;height: 100%;min-height: 0;.left {min-width: 256px;padding: 5px;height: 100%;box-sizing: border-box;box-shadow: 0 0 0 1px var(--el-input-border-color, var(--el-border-color)) inset;}.right {display: flex;flex-direction: column;margin-left: 20px;width: calc(100% - 276px);height: 100%;min-height: 0;}}.xiang{margin-left: 10px;color: #1890FF;font-weight: 550;cursor: pointer;}